import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Like, Repository, Between, IsNull, Not } from 'typeorm';
import WipShutdownList from '@main/entities/service/admin/wip/wip-shutdown-list.entity';
import WipOrderReport from '@main/entities/service/admin/wip/wip-order-report.entity';
import BaseMachine from '@main/entities/service/admin/base/base-machine.entity';
import BaseShift from '@main/entities/service/admin/base/base-shift.entity';
import { UtilService } from '@main/shared/services/util.service';
import { BaseShutdownReasonService } from '@main/service/modules/admin/base/shutdownReason/shutdownReason.service';
import { ApiException } from '@main/common/exceptions/api.exception';
import { generateExcelFn } from '@main/excel';
import { SysOperationLogService } from '../../system/operationLog/operationLog.service';
import { format } from 'date-fns';

@Injectable()
export class WipShutdownListService {
  constructor(
    private baseShutdownReasonService: BaseShutdownReasonService,
    @InjectRepository(WipShutdownList)
    private shutdownListRepository: Repository<WipShutdownList>,
    @InjectRepository(WipOrderReport)
    private orderReportRepository: Repository<WipOrderReport>,
    private util: UtilService,
    @InjectRepository(BaseMachine)
    private machineRepository: Repository<BaseMachine>,
    @InjectRepository(BaseShift) private shiftRepository: Repository<BaseShift>,
    private operationLogService: SysOperationLogService
  ) {}

  async list() {
    return await this.shutdownListRepository.find();
  }

  /**
   * 罗列所有配置
   */
  async page(data) {
    const { pageSize, pageNum, entity = {} } = data;

    const { orderCode, shutdownReasonCode, machineCode, shiftCode, createTime, ids = [] } = entity;

    const where = {
      orderCode: Like(`%${orderCode}%`),
      shutdownEndTime: Not(IsNull()),
      // shutdownReasonCode: Like(`%${shutdownReasonCode}%`),
      shiftCode: Like(`%${shiftCode}%`),
      machineCode: Like(`%${machineCode}%`),
    };

    if (shutdownReasonCode) {
      where['shutdownReasonCode'] = Like(`%${shutdownReasonCode}%`);
    }

    if (createTime && createTime.length) {
      where['createTime'] = Between(createTime[0], createTime[1]);
    }

    if (ids && ids.length) {
      where['id'] = In(ids);
    }

    const [list, total] = await this.shutdownListRepository.findAndCount({
      where,
      order: {
        updateTime: 'DESC',
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize,
    });

    const newList = await Promise.all(
      list?.map(async (item) => {
        const { machineCode, shiftCode, shutdownStartTime, shutdownEndTime } = item;
        if (shutdownStartTime) {
          item.shutdownStartTime = format(new Date(shutdownStartTime), 'yyyy-MM-dd HH:mm:ss') as any;
        }
        if (shutdownEndTime) {
          item.shutdownEndTime = format(new Date(shutdownEndTime), 'yyyy-MM-dd HH:mm:ss') as any;
        }
        const obj = await this.machineRepository.findOne({ where: { machineCode } });
        const obj1 = await this.shiftRepository.findOne({ where: { shiftCode } });
        return {
          ...(obj || {}),
          ...(obj1 || {}),
          ...item,
        };
      })
    );
    return [newList, total];
  }

  async export(dto, lang) {
    const [list] = await this.page(dto);

    if (!list || !(list as any).length) {
      throw new ApiException(10052);
    }

    const dataList = list;

    return await generateExcelFn(
      {
        sheetName: 'shutdownList',
        mainHeaderList: [
          {
            label: 'shutdownCode',
          },
          {
            label: 'erpNo',
          },
          {
            label: 'reportCode',
          },
          {
            label: 'orderCode',
          },
          {
            label: 'machineName',
          },
          {
            label: 'customTypeName',
          },
          {
            label: 'shutdownReasonCode',
          },
          {
            label: 'shutdownReasonName',
          },
          {
            label: 'shutdownStartTime',
          },
          {
            label: 'shutdownEndTime',
          },
          {
            label: 'shiftName',
          },
          {
            label: 'materialCode',
          },
          {
            label: 'materialName',
          },
          {
            label: 'remark',
          },
        ],
        dataList,
      },
      lang
    );
  }

  /**
   * 新增
   */
  async add(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const { machineStatus, orderCode, machineCode } = data;

    const orderReportObj = await this.orderReportRepository.findOne({
      where: { orderCode, machineCode, reportFinishStatus: 0 },
    });

    if (orderReportObj) {
      const { reportCode } = orderReportObj;

      if (machineStatus) {
        const shutdownObj = await this.shutdownListRepository.findOne({
          where: { reportCode, machineCode, shutdownEndTime: IsNull() },
          order: { createTime: 'DESC' },
        });

        if (shutdownObj) {
          const { id, shutdownStartTime } = shutdownObj;

          const shutdownEndTime = new Date().getTime();

          const shutdownDuration = Math.ceil(
            (shutdownEndTime - Number(shutdownStartTime)) / 60 / 1000
          );

          // console.log('shutdownDuration', shutdownDuration);

          await this.shutdownListRepository.update(
            { id },
            { shutdownEndTime, shutdownDuration }
          );

          databaseOperationLogList.push({
            type: 'update',
            dataType: 'obj',
            database: 'WipShutdownList',
            checkOnlyKeyList: [],
            data: { shutdownEndTime, shutdownDuration },
            whereObj: { id },
            remark: `WipShutdownList表更新停机记录信息`,
          });

          await this.operationLogService.add(
            {
              type: 'update',
              msg: `停机记录管理模块更新停机记录`,
              databaseOperationLogList,
              remark: `更新停机记录${data.shutdownReasonName}`,
              mac,
              ip,
              syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
            },
            user
          );
        }
      } else {
        const shutdownObj = await this.shutdownListRepository.findOne({
          where: { reportCode, machineCode, shutdownEndTime: IsNull() },
          order: { createTime: 'DESC' },
        });

        if (!shutdownObj) {
          const shutdownCode = `TJ${this.util.nowDateValue()}${this.util.generateRandomNumberValue(
            4
          )}`;

          const obj = {
            ...data,
            shutdownCode,
            reportCode,
            shutdownStartTime: new Date().getTime(),
            createName: user.nickName,
            createUserName: user.userName,
            updateName: user.nickName,
            updateUserName: user.userName,
          };

          delete obj.id;

          delete obj.createTime;

          delete obj.updateTime;

          const shutdownList = await this.shutdownListRepository.insert(obj);
          databaseOperationLogList.push({
            type: 'add',
            dataType: 'obj',
            database: 'WipShutdownList',
            checkOnlyKeyList: [],
            data: shutdownList,
            whereObj: null,
            remark: `WipShutdownList表新增数据`,
          });

          await this.operationLogService.add(
            {
              type: 'add',
              msg: `停机记录管理模块新增停机记录`,
              databaseOperationLogList,
              remark: `新增停机记录${data.shutdownReasonName}`,
              mac,
              ip,
              syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
            },
            user
          );
        }
      }
    }
  }

  /**
   * 更新
   */
  async update(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const { id, shutdownReasonName, shutdownReasonCode, remark } = data;

    if (shutdownReasonCode && shutdownReasonName) {
      const res = await this.baseShutdownReasonService.isExistCode(shutdownReasonCode);

      if (!res) {
        await this.baseShutdownReasonService.add(
          {
            shutdownReasonName,
            shutdownReasonCode,
            downtimeReasonGroudCode: '10',
            remark: '',
          },
          user,
          mac,
          ip,
          syncHostSqlite
        );
      }
    }

    await this.shutdownListRepository.update(
      { id },
      {
        shutdownReasonName,
        shutdownReasonCode,
        remark,
        updateName: user.nickName,
        updateUserName: user.userName,
      }
    );
    databaseOperationLogList.push({
      type: 'update',
      dataType: 'obj',
      database: 'WipShutdownList',
      checkOnlyKeyList: [],
      data: {
        shutdownReasonName,
        shutdownReasonCode,
        remark,
        updateName: user.nickName,
        updateUserName: user.userName,
      },
      whereObj: { id },
      remark: `WipShutdownList表更新停机记录信息`,
    });
    await this.operationLogService.add(
      {
        type: 'update',
        msg: `停机记录管理模块更新停机记录`,
        databaseOperationLogList,
        remark: `更新停机记录${data.shutdownReasonName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 删除
   */
  async delete(idList: number[], user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];
    await this.shutdownListRepository.delete(idList);
    databaseOperationLogList.push({
      type: 'delete',
      dataType: 'array',
      database: 'WipShutdownList',
      checkOnlyKeyList: [],
      data: null,
      whereObj: idList,
      remark: `WipShutdownList表删除停机记录信息`,
    });
    await this.operationLogService.add(
      {
        type: 'delete',
        msg: `停机记录管理模块删除停机记录信息`,
        databaseOperationLogList,
        remark: `删除停机记录信息`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  async byOrderCode(data) {
    const { orderCode } = data;

    const orderReportObj = await this.orderReportRepository.findOne({
      where: { orderCode, reportFinishStatus: 0 },
    });

    if (orderReportObj) {
      const { reportCode } = orderReportObj;

      const shutdownList = await this.shutdownListRepository.find({ where: { reportCode } });

      return shutdownList;
    }

    return [];
  }
}
